package vboot.core.module.bpm.proc.main;

import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.web.bind.annotation.*;
import vboot.core.common.mvc.api.R;
import vboot.core.common.mvc.dao.JdbcDao;
import vboot.core.common.mvc.dao.Sqler;
import vboot.core.common.mvc.pojo.ZidNamePid;
import vboot.core.common.utils.db.DbType;
import vboot.core.common.utils.web.XuserUtil;
import vboot.core.module.ass.oss.main.AssOssMainService;
import vboot.core.module.bpm.task.main.BpmTaskMain;
import vboot.core.module.bpm.task.main.BpmTaskMainService;
import vboot.core.module.sys.org.role.SysOrgRoleTreeService;
import vboot.core.module.sys.org.root.SysOrg;

import java.util.*;

@RestController
@RequestMapping("bpm/proc/main")
public class BpmProcMainApi {

    @GetMapping
    public R get(String name, String catid) {
        Sqler sqler = new Sqler("bpm_proc_main");
        sqler.addLike("t.name", name);
        return R.ok(service.findPageData(sqler));
    }

    @GetMapping("one/{id}")
    public R getOne(@PathVariable String id) {
        BpmProcMain main = service.findOne(id);
        return R.ok(main);
    }

    @GetMapping("zbpm")
    public R zbpm(String proid) {
        Map<String, Object> map = new HashMap<>();
        //审批记录
        Sqler sqler = new Sqler("t.id,t.crtim,t.facna,t.facno,t.opnot,t.opinf,o.name haman,t.atids", "bpm_audit_main");
        sqler.addInnerJoin("", "sys_org o", "o.id=t.haman");
        sqler.addEqual("t.proid", proid);
        sqler.addOrder("t.crtim");
        List<Map<String, Object>> audits = jdbcDao.findMapList(sqler);

        for (Map<String, Object> audit : audits) {
            if(audit.get("atids")!=null){

//               String[] atarr= (audit.get("atids")+"").split(",");
//                List<AssOssMain> atts=new ArrayList<>();
//                for (String s : atarr) {
//                    atts.add(ossService.getInfo(s));
//                }
                audit.put("atts",ossService.getInfos(audit.get("atids")+""));
            }
        }
        map.put("audits", audits);

        //历史处理人
        String hiHamen = "";
        for (Map<String, Object> audit : audits) {
            if (!hiHamen.contains((String)audit.get("haman"))) {
                hiHamen += audit.get("haman") + ";";
            }
        }
        if (hiHamen.contains(";")) {
            hiHamen = hiHamen.substring(0, hiHamen.length() - 1);
        }
        map.put("hiHamen", hiHamen);

        //当前处理人与当前用户是否在当前处理人中
        String sql2 = "select n.id as tasid,t.id as nodid,o.name exnam,n.exman,t.proid,t.facno,t.facna from bpm_node_main t" +
                " inner join bpm_task_main n on n.nodid=t.id " +
                "inner join sys_org o on o.id=n.exman " +
                "where t.proid=? and n.actag=1 order by n.ornum";
        Sqler sqler2 = new Sqler("n.id as tasid,t.id as nodid,o.name exnam,n.exman,t.proid,t.facno,t.facna,n.type tasty", "bpm_node_main");
        sqler2.addInnerJoin("", "bpm_task_main n", "n.nodid=t.id");
        sqler2.addInnerJoin("", "sys_org o", "o.id=n.exman");
        sqler2.addWhere("t.proid=? and n.actag=1", proid);
        sqler2.addOrder("n.ornum");
        List<Map<String, Object>> tasks = jdbcDao.findMapList(sqler2);
        String cuExmen = "";
        boolean cutag = false;
        String userId = XuserUtil.getUserId();

        String postSql = "select pid as id from sys_org_post_org where oid=?";
        List<String> postIdList = jdbcDao.findStringList(postSql, userId);
        Zbpm zbpm = new Zbpm();
        for (Map<String, Object> task : tasks) {
            if (StrUtil.isBlank(zbpm.getProid())) {
                zbpm.setProid((String)task.get("proid"));
                zbpm.setNodid((String)task.get("nodid"));
                zbpm.setFacno((String)task.get("facno"));
                zbpm.setFacna((String)task.get("facna"));
            }
            cuExmen += task.get("exnam") + ";";
            if (userId.equals(task.get("exman"))) {
                zbpm.setTasid((String)task.get("tasid"));
                zbpm.setTasty((String)task.get("tasty"));
                zbpm.setExman((String)task.get("exman"));
                cutag = true;
            }
            if (!cutag) {
                for (String postId : postIdList) {
                    if (postId.equals(task.get("exman"))) {
                        zbpm.setTasid((String)task.get("tasid"));
                        zbpm.setTasty((String)task.get("tasty"));
                        zbpm.setExman((String)task.get("exman"));
                        cutag = true;
                    }
                }
            }
        }
        if (cuExmen.contains(";")) {
            cuExmen = cuExmen.substring(0, cuExmen.length() - 1);
        }
        map.put("cuExmen", cuExmen);
        map.put("cutag", cutag);
        map.put("zbpm", zbpm);
        return R.ok(map);
    }

    @GetMapping("target")
    public R target(String proid, String facno,String modty) {
        Map<String, Object> map = new HashMap<>();
        Znode nextNode;
        //如果是之前被驳回的节点则，通过后要判断是否直接返回驳回的节点
        String refuseSql = "select t.id \"id\",t.paval \"paval\" from bpm_proc_param t where t.proid=? and t.pakey=?";
        Map<String, Object> bacMap = jdbcDao.findMap(refuseSql, proid, facno + "#refuse");

        String xmlSql = "select t.chxml from bpm_proc_tmpl t " +
                "inner join bpm_proc_main m on m.tmpid=t.id  where m.id=?";
        String chxml = jdbcDao.findOneString(xmlSql, proid);
        if (bacMap != null && StrUtil.isNotBlank((String) bacMap.get("paval"))) {
            nextNode = hand.getNodeInfo(chxml, (String) bacMap.get("paval"));
        } else {
            List<BpmTaskMain> bpmTaskMainList = taskMainService.findAllByProidNotActive(proid);
            if (bpmTaskMainList.size() > 0) {
                nextNode = hand.getNodeInfo(chxml, facno);
            } else {
                Zcond zcond=new Zcond();
                zcond.setProid(proid);
                zcond.setModty(modty);
                nextNode = hand.calcTarget(zcond,chxml, facno);
            }
        }
        String tamen = "暂时无法计算";
        if (nextNode == null)
        {
            nextNode = new Znode();
            nextNode.setFacno("NX");
            nextNode.setFacna("未知节点");
        }else{
            tamen = calcTamen(proid,nextNode.getExmen());
        }
        map.put("tarno", nextNode.getFacno());
        map.put("tarna", nextNode.getFacna());
        map.put("tamen", tamen);
        if (bacMap != null) {
            map.put("bacid", bacMap.get("id"));
        }
        return R.ok(map);
    }


    //返回当前节点之前的已走过的节点
    @GetMapping("refnodes")
    public R refNodes(String proid, String facno) {
        String sql = "select distinct t.facno \"id\",t.facna \"name\",t.haman \"exman\",t.crtim \"crtim\" from bpm_audit_main t " +
                "where proid=? and opkey in('dsubmit','pass') order by t.crtim";
        List<Map<String, Object>> mapList = jdbcDao.findMapList(sql, proid);
        List<Map<String, Object>> list = new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            if (facno.equals(map.get("id"))) {
                break;
            }
            boolean flag=false;
            for (Map<String, Object> map2 : list) {
                if (map.get("id").equals(map2.get("id"))) {
                    flag=true;
                    break;
                }
            }
            if(!flag){
                list.add(map);
            }
        }
        return R.ok(list);
    }

    //返回当前节点沟通人员
    @GetMapping("ccmen")
    public R ccmen(String proid, String facno) {
        String sql = "select o.id \"id\",o.name \"name\",t.id \"tasid\" from bpm_task_main t " +
                "inner join sys_org o on o.id=t.exman " +
                "where t.proid=? and t.type='communicate' order by t.sttim";
        List<Map<String, Object>> mapList = jdbcDao.findMapList(sql, proid);
        return R.ok(mapList);
    }

    @GetMapping("xml")
    public R xml(String proid) {
        Map<String, Object> map = new HashMap<>();
        String xmlSql = "select t.orxml id from bpm_proc_tmpl t " +
                "inner join bpm_proc_main m on m.tmpid=t.id where m.id=?";
        String orxml = jdbcDao.findOneString(xmlSql, proid);

//        String sql = "select distinct t.facno id from bpm_node_hist t where proid=? order by sttim";
        String sql = "select distinct t.facno id from bpm_node_hist t where proid=?";
        List<String> nodeList = jdbcDao.findStringList(sql, proid);

        List<ZidNamePid> allLineList = hand.GetAllLineList(orxml);
        HashSet<String> lineSet = new HashSet<>();
        for (ZidNamePid zinp : allLineList) {
            for (String node : nodeList) {
                if (node.equals(zinp.getName())) {
                    for (String node2 : nodeList) {
                        if (node2.equals(zinp.getPid())) {
                            lineSet.add(zinp.getId());
                            break;
                        }
                    }
                    break;
                }
            }
        }

        map.put("xml", orxml);
        map.put("nodeList", nodeList);
        map.put("lineList", lineSet);
        return R.ok(map);
    }

    @GetMapping("texml")
    public R texml(String tmpid) {
        Map<String, Object> map = new HashMap<>();
        String sql = "select t.orxml from bpm_proc_tmpl t where t.id=?";
        String orxml = jdbcDao.findOneString(sql, tmpid);
        Znode nextNode = hand.getFirstNode(orxml, "N1");

        String tamen = "暂时无法计算";
        if (nextNode == null)
        {
            nextNode = new Znode();
            nextNode.setFacno("NX");
            nextNode.setFacna("未知节点");
        }else{
            tamen = calcTamen(null,nextNode.getExmen());
        }
        map.put("tarno", nextNode.getFacno());
        map.put("tarna", nextNode.getFacna());
        map.put("tamen", tamen);
        map.put("xml", orxml);
        return R.ok(map);
    }

    private String calcTamen(String proid,String exman) {
        String tamen = "";
        if (StrUtil.isNotBlank(exman) && !exman.contains(";")) {
            String tamenSql = "select t.id, t.name,t.type from sys_org t where t.id=?";
            SysOrg sysOrg = jdbcDao.getTp().queryForObject(tamenSql,
                    new Object[]{exman}, new BeanPropertyRowMapper<>(SysOrg.class));
            if (sysOrg.getType()==32) {
                String crmid=XuserUtil.getUserId();
                if(proid!=null){
                    String sql="select crmid from bpm_proc_main where id=?";
                    crmid= jdbcDao.findOneString(sql,proid);
                }
                SysOrg org = sysOrgRoleTreeService.calc(crmid, sysOrg.getId());
                tamen = org.getName();
            } else {
                tamen = sysOrg.getName();
            }
        } else if (StrUtil.isNotBlank(exman) && exman.contains(";")) {
            Sqler sqler = new Sqler("sys_org");
            String ids = exman;
            ids = "'" + ids.replaceAll(";", "','") + "'";
            sqler.addWhere("id in " + "(" + ids + ")");
            if (DbType.MYSQL.equals(jdbcDao.getDbType())) {
                sqler.addOrder("field(id," + ids + ")");
            }else if(DbType.ORACLE.equals(jdbcDao.getDbType())){
                sqler.addOrder("INSTR('"+ids.replaceAll("'","")+"',id)");
            }else if(DbType.SQL_SERVER.equals(jdbcDao.getDbType())){
                sqler.addOrder("CHARINDEX(id,'"+ids.replaceAll("'","")+"')");
            }

            sqler.addSelect("t.type");
            System.out.println(sqler.getSql());
            List<SysOrg> list = jdbcDao.getTp().query(sqler.getSql(), sqler.getParams(),
                    new BeanPropertyRowMapper<>(SysOrg.class));
//            List<ZidName> idNameList = jdbcDao.findIdNameList(sqler);
            for (SysOrg sysOrg : list) {
                if (sysOrg.getType() == 32) {
                    String crmid=XuserUtil.getUserId();
                    if(proid!=null){
                        String sql="select crmid from bpm_proc_main where id=?";
                        crmid= jdbcDao.findOneString(sql,proid);
                    }
                    SysOrg org = sysOrgRoleTreeService.calc(crmid, sysOrg.getId());
                    tamen += org.getName() + ";";
                } else {
                    tamen += sysOrg.getName() + ";";
                }
            }
            tamen = tamen.substring(0, tamen.length() - 1);
        }
        return tamen;
    }

//    @PostMapping("hpass")
//    public R hpass(@RequestBody Zbpm zbpm) {
//
//
//        service.handlerPass(zbpm);
//        return R.ok();
//    }

//    @PostMapping("hrefuse")
//    public R hrefuse(@RequestBody Zbpm zbpm) {
//
//        service.handlerRefuse(zbpm);
//        return R.ok();
//    }

    @PostMapping
    public R post(@RequestBody BpmProcMain main) {
        return R.ok(service.insert(main));
    }

    @PutMapping
    public R put(@RequestBody BpmProcMain main) {
        return R.ok(service.update(main));
    }

    @DeleteMapping("{ids}")
    public R delete(@PathVariable String[] ids) {
        return R.ok(service.delete(ids));
    }

    @Autowired
    private JdbcDao jdbcDao;

    @Autowired
    private BpmProcMainHand hand;

    @Autowired
    private AssOssMainService ossService;

    @Autowired
    private BpmProcMainService service;

    @Autowired
    private BpmTaskMainService taskMainService;

    @Autowired
    private SysOrgRoleTreeService sysOrgRoleTreeService;

}
